package com.systemCapacity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.systemCapacity.common.dto.AttributeDto;
import com.systemCapacity.common.dto.BlueAttributeDto;
import com.systemCapacity.common.dto.BlueEquipmentDto;
import com.systemCapacity.entity.Attribute;
import com.systemCapacity.entity.Device;
import com.systemCapacity.entity.Enum.AttributeType;
import com.systemCapacity.entity.Enum.AttributeValueType;
import com.systemCapacity.mapper.AttributeMapper;
import com.systemCapacity.service.AttributeService;
import com.systemCapacity.service.DeviceService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class AttributeServiceImpl extends ServiceImpl<AttributeMapper, Attribute> implements AttributeService {
    @Autowired
    AttributeMapper attributeMapper;

    @Autowired
    DeviceService deviceService;

    @Override
    public List<AttributeDto> getTemplateAttributes(String templateId) {
        QueryWrapper<Attribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attributeType", AttributeType.TEMPLATE.getValue());
        queryWrapper.eq("templateId", templateId);
        List<Attribute> attributes = attributeMapper.selectList(queryWrapper);
        return attributes.stream()
                .map(attribute -> BeanUtil.copyProperties(attribute, AttributeDto.class)).collect(Collectors.toList());
    }

    @Override
    public List<AttributeDto> getEquipmentAttributes(String equipmentId) {
        QueryWrapper<Attribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attributeType", AttributeType.EQUIPMENT.getValue());
        queryWrapper.eq("equipmentId", equipmentId);
        List<Attribute> attributes = attributeMapper.selectList(queryWrapper);
        List<AttributeDto> attributeDtos = new ArrayList<>();
        if(!attributes.isEmpty()){
            attributeDtos = attributes.stream().map(attribute -> {
                AttributeDto attributeDto = BeanUtil.copyProperties(attribute, AttributeDto.class);
                List<Double> values = new ArrayList<>();
                if(attribute.getValue() != null){
                    for (String value : attribute.getValue().split(";")) {
                        if(!StringUtils.isEmpty(value) && !"null".equals(value)){
                            values.add(Double.parseDouble(value));
                        }
                    }
                }
                attributeDto.setValues(values);
                return attributeDto;
            }).collect(Collectors.toList());
        }
        return attributeDtos;
    }

    @Override
    public List<BlueEquipmentDto> getEquipmentBlueAttributes(String equipmentId) {
        QueryWrapper<Attribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attributeType", AttributeType.EQUIPMENT.getValue());
        queryWrapper.eq("equipmentId", equipmentId);
        queryWrapper.isNotNull("deviceId");
        List<Attribute> attributes = attributeMapper.selectList(queryWrapper);
        //按装备名称分组
        Map<String, List<Attribute>> groupByDeviceId = attributes.stream().collect(Collectors.groupingBy(x -> x.getDeviceId()));
        List<BlueEquipmentDto> equipmentDtoList = new ArrayList<>();
        groupByDeviceId.forEach((k,v) -> {
            BlueEquipmentDto blueEquipmentDto = new BlueEquipmentDto();
            Device device = deviceService.getById(k);
            blueEquipmentDto.setEquipmentName(device.getDeviceName());
            blueEquipmentDto.setEquipmentId(equipmentId);
            blueEquipmentDto.setDeviceId(device.getDeviceId());
            blueEquipmentDto.setWeight(device.getWeight());
            List<BlueAttributeDto> blueAttributeDtoList = v.stream().map(x -> {
                BlueAttributeDto blueAttributeDto = new BlueAttributeDto();
                blueAttributeDto.setAttributeType(x.getAttributeType().getValue());
                blueAttributeDto.setAttributeName(x.getAttributeName());
                blueAttributeDto.setEquipmentName(x.getEquipmentName());
                blueAttributeDto.setAttributeId(x.getAttributeId());
                blueAttributeDto.setAttributeValueType(x.getAttributeValueType() != null ? x.getAttributeValueType().getValue() : null);
                blueAttributeDto.setEquipmentId(x.getEquipmentId());
                blueAttributeDto.setUnit(x.getUnit());
                List<Double> values = new ArrayList<>();
                if(x.getValue() != null){
                    for (String value : x.getValue().split(";")) {
                        values.add(Double.parseDouble(value));
                    }
                }
                blueAttributeDto.setValues(values);
                return blueAttributeDto;
            }).collect(Collectors.toList());
            blueEquipmentDto.setAttributeList(blueAttributeDtoList);
            equipmentDtoList.add(blueEquipmentDto);
        });

        return equipmentDtoList;
    }

    @Override
    public String getEquipmentBlueAttributesDesc(String equipmentId,String deviceId) {
        QueryWrapper<Attribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attributeType", AttributeType.EQUIPMENT.getValue());
        queryWrapper.eq("equipmentId", equipmentId);
        queryWrapper.eq("deviceId", deviceId);
        List<Attribute> attributes = attributeMapper.selectList(queryWrapper);
        //获取参数描述
        StringBuilder sb = new StringBuilder();
        if (!attributes.isEmpty()) {
            for (Attribute attribute : attributes) {
                if(attribute.getAttributeValueType() != null){
                    if(attribute.getAttributeValueType().equals(AttributeValueType.NUMERIC)){
                        sb.append(attribute.getAttributeName() + ":" + attribute.getValue() + attribute.getUnit() + "\n");
                    }else{
                        String[] values = attribute.getValue().split(";");
                        sb.append(attribute.getAttributeName() + ":" + values[0] + attribute.getUnit() + " ~ " + values[1] + attribute.getUnit() + "\n");
                    }
                }
            }
        }

        return sb.toString();
    }

    /**
     * 保存属性
     * @param id 模板或装备id
     * @param dto 属性
     * @return 操作结果
     */
    @Override
    public boolean saveAttribute(String id, AttributeDto dto) {
        Attribute attribute = BeanUtil.copyProperties(dto, Attribute.class);
        attribute.setAttributeId(UUID.randomUUID().toString());
        switch (dto.getAttributeType()) {
            case TEMPLATE:
                attribute.setTemplateId(id);
                break;
            case EQUIPMENT:
                attribute.setEquipmentId(id);
                StringBuilder stringBuilder = new StringBuilder();
                for (Double value : dto.getValues()) {
                    stringBuilder.append(value);
                    stringBuilder.append(";");
                }
                stringBuilder.setLength(Math.max(stringBuilder.length() - 1, 0));
                attribute.setValue(stringBuilder.toString());
                break;
        }
        save(attribute);
        return true;
    }

    /**
     * 给定属性，查找模板属性的父属性
     * @param dto 装备属性
     * @param templateId 装备id
     * @return 父属性id
     */
    @Override
    public Attribute getParentAttribute(AttributeDto dto, String templateId) {
        QueryWrapper<Attribute> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("attributeId", dto.getPid())
                .eq("templateId", templateId);
        return getOne(queryWrapper);
    }

    @Override
    public boolean editAttribute(AttributeDto dto) {
        LambdaUpdateWrapper<Attribute> lambdaUpdateWrapper;
        if (dto.getAttributeType() == AttributeType.TEMPLATE) {
            lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(Attribute::getAttributeId, dto.getAttributeId());
            lambdaUpdateWrapper.set(Attribute::getAttributeName, dto.getAttributeName());
            lambdaUpdateWrapper.set(Attribute::getAttributeValueType, dto.getAttributeValueType());
            lambdaUpdateWrapper.set(Attribute::getUnit, dto.getUnit());
        } else {// 装备只修改值
            List<Double> values = dto.getValues();
            StringBuilder stringBuilder = new StringBuilder();
            for (Double value : values) {
                stringBuilder.append(value);
                stringBuilder.append(";");
            }
            stringBuilder.setLength(Math.max(stringBuilder.length() - 1, 0));
            lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(Attribute::getAttributeId, dto.getAttributeId())
                    .set(Attribute::getValue, stringBuilder.toString());
        }
        update(lambdaUpdateWrapper);
        return true;
    }

    @Override
    public boolean editBlueAttribute(List<BlueAttributeDto> attributeDtoList) {
        for (BlueAttributeDto blueAttributeDto : attributeDtoList) {
            if(StringUtils.isEmpty(blueAttributeDto.getAttributeName())){
                continue;
            }
            List<Double> values = blueAttributeDto.getValues();
            String valueStr = "";
            if (!values.isEmpty()) {
                valueStr = values.stream().map(x -> x.toString()).collect(Collectors.joining(";"));
            }
            Attribute attribute = new Attribute();
            BeanUtils.copyProperties(blueAttributeDto,attribute);
            attribute.setAttributeType(AttributeType.EQUIPMENT);
            attribute.setAttributeValueType(blueAttributeDto.getAttributeValueType() == 0 ? AttributeValueType.NUMERIC : AttributeValueType.RANGE);
            attribute.setValue(valueStr);
            if(attribute.getAttributeId() == null){
                attribute.setAttributeId(UUID.randomUUID().toString());
            }
            saveOrUpdate(attribute);
        }

        return true;
    }

    /**
     *
     * @param dto 模型属性
     * @return 操作结果
     */
    @Override
    public boolean updateChildAttribute(AttributeDto dto) {
        LambdaUpdateWrapper<Attribute> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        lambdaUpdateWrapper.eq(Attribute::getPid, dto.getPid())
                .set(Attribute::getAttributeName, dto.getAttributeName())
                .set(Attribute::getAttributeValueType, dto.getAttributeValueType())
                .set(Attribute::getUnit, dto.getUnit());
        List<Double> values = dto.getValues();
        if (values != null && !values.isEmpty()) {
            StringBuilder stringBuilder = new StringBuilder();
            for (Double value : values) {
                stringBuilder.append(value);
                stringBuilder.append(";");
            }
            lambdaUpdateWrapper.set(Attribute::getValue, stringBuilder.toString());
        }
        update(lambdaUpdateWrapper);
        return true;
    }
}
